#include "ics307.h"

void ICS307_IO_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; 
  RCC_AHB1PeriphClockCmd(RCC_ICS307_CLK_Periph_GPIO|RCC_ICS307_DATA_Periph_GPIO|RCC_ICS307_STROBE_Periph_GPIO , ENABLE);  
  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	
	
  GPIO_InitStructure.GPIO_Pin = ICS307_CLK;
  GPIO_Init(ICS307_CLK_Periph_GPIO,&GPIO_InitStructure);
	
  GPIO_InitStructure.GPIO_Pin = ICS307_DATA;
  GPIO_Init(ICS307_DATA_Periph_GPIO,&GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = ICS307_STROBE;
  GPIO_Init(ICS307_STROBE_Periph_GPIO,&GPIO_InitStructure);

	
}

u32 calculate_idt307_config(float output_clk)
{
		u32 idt307_config = 0x300000;
		u32 VDW, RDW, OD, valid_VDW = 0, valid_RDW = 0, true_OD = 0, valid_OD = 0;
		float x, y, tol = 10, tol_temp;
		for (OD = 2; OD < 11; OD++)
		{
				if (OD == 9)
				{
						continue;
				}
				else
				{
						x = output_clk * (float)OD / (float)50.0;
						if ((x > (float)1.1) && (x <= (float)8))
						{
								for (RDW = 1; RDW < 128; RDW += 1)
								{
										for (VDW = 4; VDW < 512; VDW += 1)
										{
												y = ((float)(VDW + 8)) / ((float)(RDW + 2));
												if ((y > 1.1) && (y <= 8))
												{
														if (y > x)
														{
																tol_temp = y - x;
														}
														else
														{
																tol_temp = x - y;
														}
														if (tol_temp < tol)
														{
																valid_RDW = RDW;
																valid_VDW = VDW;
																valid_OD = OD;
																tol = tol_temp;
														}
												}
										}
								}
						}
				}
		}
		switch (valid_OD)
		{
				case 2:
						true_OD = 1;
						break;
				case 3:
						true_OD = 6;
						break;
				case 4:
						true_OD = 3;
						break;
				case 5:
						true_OD = 4;
						break;
				case 6:
						true_OD = 7;
						break;
				case 7:
						true_OD = 5;
						break;
				case 8:
						true_OD = 2;
						break;
				case 10:
						true_OD = 0;
						break;
		}
		idt307_config = idt307_config | (true_OD << 16) | (valid_VDW << 7) | valid_RDW;
		return idt307_config;
}

void ICS307_HighLow_Set(float pclk,u32 ICS307_Data)
{
    if(pclk>100)
    {
        ISC307_config(ICS307_Data);
        delay_ms(15);            //如果出现不正常的线条，可加大延时
    }
}    

void ICS307_ValidClk_Set(u32 ICS307_Data)
{
        ISC307_config(ICS307_Data);
        delay_ms(15);            //如果出现不正常的线条，可加大延时
}

void ISC307_config(u32 config)
{
	u8 i;	
	GPIO_ResetBits( ICS307_CLK_Periph_GPIO,			ICS307_CLK);		//ISC_CLK_TRIS = 0;
	GPIO_ResetBits( ICS307_STROBE_Periph_GPIO,  ICS307_STROBE);	//ISC_STROBE_TRIS = 0;
	delay_us(5);
	for(i = 0; i < 24; i++)
	{
		if((config >> (23 - i)) & 0x1)
			GPIO_SetBits	( ICS307_DATA_Periph_GPIO,  	ICS307_DATA);		//ISC_DIN_TRIS = 1;
		else
			GPIO_ResetBits( ICS307_DATA_Periph_GPIO,  	ICS307_DATA);		//ISC_DIN_TRIS = 0;
//		delay_us(1);
		GPIO_SetBits	( ICS307_CLK_Periph_GPIO,			ICS307_CLK);		//ISC_CLK_TRIS = 1;
//		delay_us(1);
		GPIO_ResetBits( ICS307_CLK_Periph_GPIO,			ICS307_CLK);		//ISC_CLK_TRIS = 0;
	}
//	delay_us(1);
	GPIO_SetBits	( ICS307_STROBE_Periph_GPIO,  ICS307_STROBE);	//ISC_STROBE_TRIS = 1;
	delay_us(5);
	GPIO_ResetBits( ICS307_STROBE_Periph_GPIO,  ICS307_STROBE);	//ISC_STROBE_TRIS = 0;
}

